/**
 * Copyright (C), 2021, cyz.tools
 * FileName: MainService
 * Author:   chenyz
 * Date:     2021/2/17 下午4:39
 * Description: 1
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package org.cyz.tools.service;

import cn.hutool.core.util.ObjectUtil;
import com.sun.javafx.scene.control.LabeledText;
import javafx.application.Platform;
import javafx.event.EventHandler;
import javafx.scene.Cursor;
import javafx.scene.control.TextField;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;
import javafx.util.Callback;
import org.cyz.tools.common.GlobalConstant;
import org.cyz.tools.common.bean.DBInfo;
import org.cyz.tools.common.bean.ResultBean;
import org.cyz.tools.common.bean.Settings;
import org.cyz.tools.common.util.*;
import org.cyz.tools.common.util.sqlite.SQLiteUtil;
import org.cyz.tools.controller.BodyController;
import org.cyz.tools.core.assembly.Notify;
import org.cyz.tools.core.assembly.log.Log;
import org.cyz.tools.core.assembly.tableview.MenuTreeCell;
import org.cyz.tools.core.manager.WindowManager;

import java.util.ArrayList;
import java.util.List;


/**
 * 〈一句话功能简述〉<br> 
 * 〈1〉
 *
 * @author chenyz
 * @create 2021/2/17
 * @since 1.0.0
 */
public class MainService {

    /**
     * jedis工具
     **/
    private RedisUtil redisUtil = new RedisUtil();
    /**
     * 图标工具
     */
    private ImageUtil imageUtil = new ImageUtil();
    private ConsoleUtil consoleUtil=new ConsoleUtil();
    public TreeItem<String> rootItem;
    private TreeView treeView;
    private BodyController bodyController;

    private Stage stage;


    /**
     * 注册菜单
     * @param treeView
     * @param bodyController
     */
    protected void registerMenu(TreeView treeView, BodyController bodyController) {
        this.treeView=treeView;
        this.bodyController=bodyController;
        //设置只有鼠标移动到LabeledText才显示手的形状
        treeView.addEventFilter(MouseEvent.MOUSE_MOVED,event->{
            if(event.getTarget() instanceof LabeledText){
                treeView.setCursor(Cursor.HAND);
            }else{
                treeView.setCursor(Cursor.DEFAULT);
            }
        });

        //注册展开事件
        treeView.addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent mouseEvent) {
                if(mouseEvent.getTarget() instanceof LabeledText){
                    switch (mouseEvent.getButton()) {
                        //表示主（按钮1，通常是鼠标左键）
                        case PRIMARY:
                            registerLeftBtn();
                            break;
                        //表示鼠标中键（按钮2）
                        case MIDDLE:
                            break;
                        //表示辅助（按钮3，通常是鼠标右键)
                        case SECONDARY:
                            //单击了右键
                            registerRightBtn();
                            break;
                    }
                    RedisUtil.isOpen = true;
                }
            }
        });
    }

 static int cacheIndex=0;
    /**
     * 右键注册
     *    - 根据选择的栏目展示注册不同的菜单
     */
    private void registerRightBtn() {
        int index=Integer.valueOf(treeView.getSelectionModel().getSelectedIndices().get(0).toString());
        if(cacheIndex!=index){
            treeView.setCellFactory(new Callback<TreeView, TreeCell>() {
                @Override
                public TreeCell call(TreeView treeView) {
                    return null;
                }
            });
            cacheIndex=index;
        }
//        switch (index){
//            case 0:
//                //服务器地址
//                break;
//            case 1:
//                //数据库索引
//                break;
//
//        }
        // 单元设置，TreeView下的每个子控件都支持,包扩子子控件,所以添加菜单栏那里只对有儿子有父亲的进行设置
        treeView.setCellFactory(new Callback<TreeView, TreeCell>() {
            @Override
            public TreeCell call(TreeView treeView) {
                return new MenuTreeCell(index);
            }
        });

    }


    /**
     * 点击菜单项目
     */
    private void registerLeftBtn() {
        if (null == treeView.getSelectionModel().getSelectedItem()) {
            Log.info(MainService.class.getSimpleName(),"没有选择栏目的菜单!");
            return;
        }
        //单击了左键
        TreeItem<String> currentSelectItem = (TreeItem<String>) treeView.getSelectionModel().getSelectedItem();
        if (null == currentSelectItem) {
            return;
        }
        if (changeDB(currentSelectItem.getParent().getValue())) {
            //切换db
            redisUtil.selectDB(currentSelectItem.getParent().getValue());
        }
        String[] labName = currentSelectItem.getValue().split(":");
        //验证ip
        if (IpUtil.isIP(labName[0])) {
            if (!CommonUtil.IP_LIST.add(labName[0] + ":" + labName[1])) {
                //已经建立过连接 直接不执行
                return;
            }
            //验证是否可用的连接
            if (!IpUtil.checkIpPort(labName[0], Integer.valueOf(labName[1]))) {
                Log.info(MainService.class.getSimpleName(),"无法连接:%s", labName[0]+":"+ labName[1]);
                Notify.notify("提示", labName[0] + "地址不可达！", 4);
                CommonUtil.IP_LIST.remove(labName[0] + ":" + labName[1]);
                return;
            }

        } else {
            //不是ip则是子栏目key--> 右侧加载对应界面
            if (StringUtil.sets.contains(currentSelectItem.getValue().split(" ")[0])) {
                //是二级目录
                Log.info(MainService.class.getSimpleName()," 二级目录:%s ", currentSelectItem.getValue().split(" ")[0]);
            } else if (CommonUtil.MORE_KEY.equals(currentSelectItem.getValue())) {
                /**
                 * 加载更多的key
                 */
                Platform.runLater(() -> {
                    TreeUtil.moreKey(currentSelectItem, currentSelectItem.getParent().getValue());
                });
            } else {
                //key
                Log.info(MainService.class.getSimpleName(),"currentSelectItem->Value：" + currentSelectItem.getValue());
                showKeyResult(currentSelectItem);
            }
            return;
        }
        loadMenu(currentSelectItem,labName[0], Integer.parseInt(labName[1]));
    }

    private void loadMenu(TreeItem<String> currentSelectItem, String serverUrl, int port) {
        //重新改变redis的连接
        redisUtil.reBuilderRedis(serverUrl,port);
        //修改图标
//        currentSelectItem.getParent().setGraphic(imageUtil.getIcon("connected"));
        //启动控制台
        startConsole();
        //启动监控
        startMonitor();
        //清空之前
        currentSelectItem.getChildren().clear();
        //创建子栏目
        attrSubMenu(currentSelectItem);
    }

    /**
     * 从sqlite中读取保存的连接信息
     */
    public void initMenu() {
        List<Object> dbInfoList = SQLiteUtil.queryAll(new DBInfo());
        if (null != dbInfoList && dbInfoList.size() > 0) {
            List<DBInfo> dbInfos=new ArrayList<>();
            dbInfoList.forEach(obj->{
                dbInfos.add((DBInfo) obj);
            });
            setMenu(dbInfos);
        } else {
            //初始化
//            sqliteUtil.initDB();
            //重载
//            initMenu();
            Log.info(MainService.class.getSimpleName(),"初始化新增...");
            if(null==stage){
                stage=  new WindowManager("fxml/NewConnection.fxml").
                                isTop(true).
                                setTitle("新建连接").
                                setSize(613,700).
                                builder();
            }else{
                if(!stage.isShowing()){
                    stage.show();
                }
            }
        }
    }
    /**
     * 设置菜单
     *
     * @param dbInfoList
     */
    public void setMenu(List<DBInfo> dbInfoList) {
        // TreeItem名字和图标
        rootItem = new TreeItem<>();
        dbInfoList.forEach(dbInfo -> {
            TreeItem<String> item = new TreeItem<>();
            item.setValue(dbInfo.getHost() + ":" + dbInfo.getPort());
            item.setGraphic(ImageUtil.getIcon("connect"));
            rootItem.getChildren().add(item);
        });
        treeView.setRoot(rootItem);
        //不显示根节点
        treeView.setShowRoot(false);
        treeView.setId("-1");

        // 设置为可编辑的
//        treeView.setEditable(true);


    }


    /**
     * 是否是切换了库
     *
     * @param value
     * @return
     */
    private boolean changeDB(String value) {
        return (null != value && "db".equalsIgnoreCase(value.substring(0, 2)) && Integer.valueOf(value.split(" ")[0].substring(2)) >= 0);
    }

    public void checkVersion() {
        //检测更新
        Settings updateSettings = InitDataUtil.getSettings(InitDataUtil.UPDATE);
        if (null != updateSettings) {
            if (Boolean.valueOf(updateSettings.getValue())) {
                UpdateUtil.checkUpdate();
            }
        }
    }

    /**
     * 启用控制台
     */
    private void startConsole(){
        Platform.runLater(()->{
            consoleUtil.initConsole(bodyController.inputConsole,bodyController.showConsole);
        });
    }

    /**
     * 历史命令监控
     */
    private void startMonitor() {
       if(GlobalConstant.isStartMonitor){
           try {
               redisUtil.monitor(bodyController.monitor);
           } catch (Exception e) {
               Notify.toast("出了点问题," + e.getMessage());
           }
       }else{
           //移除监控
           redisUtil.cancelMonitor(bodyController.monitor);
       }
    }

    /**
     * 子栏目的创建
     *
     * @param currentSelectItem
     */
    private synchronized void attrSubMenu(TreeItem<String> currentSelectItem) {
        TreeUtil.attrMenuInfo(currentSelectItem);
//        Toast.notify("提示", "连接成功!", 0);
        Notify.toast("连接成功!");
    }

    /**
     * 选中key初始化右侧界面
     *
     * @param currentSelectItem
     */
    private void showKeyResult(TreeItem<String> currentSelectItem) {
        if (null != bodyController) {
            //清除控件默认值
            bodyController.clearOldValue();
            ResultBean resultBean = redisUtil.getValue(currentSelectItem.getValue());
            if (ObjectUtil.isEmpty(resultBean)) {
                Platform.runLater(() -> Notify.toast("key:" + currentSelectItem.getValue() + " 已失效或不存在!"));
                return;
            }
            //设置控件的值
            setControlValue(bodyController, resultBean, currentSelectItem);
            //将值挂在到剪贴板
            KeyBoardUtil.toClipboard(resultBean);
        }
    }


    /**
     * 设置控件的值
     *
     * @param bodyController
     * @param resultBean
     * @param currentSelectItem
     */
    private void setControlValue(BodyController bodyController, ResultBean resultBean, TreeItem<String> currentSelectItem) {
        bodyController.valueType.setText("数据类型: ");
        bodyController.valueTTL.setText("生存周期: ");
        //设置显示值类型
        bodyController.valueType.setText(bodyController.valueType.getText() + resultBean.getValueType());
        //设置生命周期 new SimpleDateFormat("HH:mm:ss").format(resultBean.getTtl())
        bodyController.valueTTL.setText(bodyController.valueTTL.getText() + DateUtil.convTime(resultBean.getTtl()));
        TextField keyName = bodyController.keyName;
        if (null != keyName) {
            keyName.setText(currentSelectItem.getValue());
            selfAdaptionResult(bodyController, resultBean);
        }
    }

    /**
     * 根据数据类型自动选择控件显示
     *
     * @param bodyController
     * @param resultBean
     */
    private void selfAdaptionResult(BodyController bodyController, ResultBean resultBean) {
        Platform.runLater(() -> bodyController.setSelfAdaptionResult(resultBean));
    }


    protected void showConnForm() {
        if(null==stage){
            stage=  new WindowManager("fxml/NewConnection.fxml").
                    isTop(false).
                    setTitle("新建连接").
                    setSize(613,700).
                    builder();
        }else{
            if(!stage.isShowing()){
                stage.show();
            }
        }
    }
}
